package edison.persistence;

import java.util.List;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PropertyType;
import javax.persistence.Query;

import edison.jcr.SessionContext;

public class HSQL implements Dialect {

	private String t(int type) {

		switch (type) {
		case PropertyType.BINARY:
			return "varbinary(255)";
		case PropertyType.BOOLEAN:
			return "boolean";
		case PropertyType.LONG:
			return "bigint";
		case PropertyType.DOUBLE:
			return "double";
		case PropertyType.DECIMAL:
			return "numeric(19,2)";
		case PropertyType.DATE:
			return "timestamp";
		case PropertyType.STRING:
			return "varchar(255)";
		case PropertyType.NAME:
		case PropertyType.PATH:
		case PropertyType.REFERENCE:
		case PropertyType.WEAKREFERENCE:
		case PropertyType.URI:
		case PropertyType.UNDEFINED:
			return "varchar(255)";
		default:
			throw new IllegalArgumentException("unknown type: " + type);
		}

	}

	/*
	 * 替换非a-zA-Z0_9字符为'_'
	 */
	private String c(String s) {
		return s.replaceAll("[^\\w]", "_");
	}

	/*
	 * Node表名
	 */
	private String n(String s) {
		return "nt__".concat(c(s));
	}

	private int exec(SessionContext context, String sql) {
		Query query = context.getEntityManager().createNativeQuery(sql);
		return query.executeUpdate();
	}

	private int exec(SessionContext context, String sql, List<ColumnValue> columns) {
		Query query = context.getEntityManager().createNativeQuery(sql);
		for (int i = 1; i <= columns.size(); i++) {
			query.setParameter(i, columns.get(i - 1).getValue());
		}
		return query.executeUpdate();
	}

	public void dropNodeTable(SessionContext context, String name) {
		String sql = String.format("drop table %s if exists", n(name));
		exec(context, sql);
	}

	public void createNodeTable(SessionContext context, String name, List<ColumnDescriptor> columns) {
		columns.add(0, new ColumnDescriptor("identifier", PropertyType.STRING));
		columns.add(1, new ColumnDescriptor("name", PropertyType.NAME));
		columns.add(1, new ColumnDescriptor("parent", PropertyType.NAME));
		StringBuilder sql = new StringBuilder(250);
		sql.append("create table ").append(n(name)).append("(");
		for (ColumnDescriptor col : columns) {
			sql.append(c(col.getName())).append(" ").append(t(col.getRequiredType())).append(',');
		}

		sql.append("primary key (identifier))");

		exec(context, sql.toString());
	}

	@SuppressWarnings("rawtypes")
	public void getPath(SessionContext context, String identify) {
		String table_sql = "select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA='PUBLIC' and LEFT(TABLE_NAME,4)=?";
		Query tableQuery = context.getEntityManager().createQuery(table_sql);
		tableQuery.setParameter(1, "nt__");
		for (Object row : tableQuery.getResultList()) {
			String tableName = ((Object[]) row)[0].toString();
			Query q = context.getEntityManager().createQuery("");
			q.
		}
	}

	public void insertNode(SessionContext context, String name, List<ColumnValue> columns) {
		// "INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)"
		StringBuilder sql = new StringBuilder(250);
		sql.append("INSERT INTO ").append(c(name)).append("(");
		for (ColumnValue col : columns) {
			sql.append(col.getName()).append(",");
		}
		sql.append(") VALUES (");

		for (int i = 0; i < columns.size(); i++) {
			sql.append("?,");
		}
		sql.append(")");

		exec(context, sql.toString().replaceAll(",\\)", ")"), columns);
	}

	public Node getNode(SessionContext context, String name) {
		Query q = context.getEntityManager().createNativeQuery("SELECT * FROM nt_test");
		Object[] row = (Object[]) q.getSingleResult();
		for (Object colunm : row) {

		}
	}

	public NodeIterator getChildNodes(SessionContext context, String path) {

	}

}
